package com.atguigu.gmall.payment.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.service.AlipayService;
import com.atguigu.gmall.payment.service.PaymentService;
import com.sun.org.apache.regexp.internal.RE;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Controller
//@RestController 作用：数据直接显示到页面 json格式  不用他是因为 后面同步回调需要重定向页面
@RequestMapping("/api/payment/alipay")
public class AlipayController {

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${app_id}")
    private String app_id;

    /**
     * 生成二维码
     * @param orderId
     * @return
     */
    @GetMapping("submit/{orderId}")
    @ResponseBody
    public String submitOrder(@PathVariable Long orderId){
        String from = null;
        try {
            from = alipayService.createaliPay(orderId);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return from;
    }

    /**
     * 支付宝回调
     * @return
     */
    @GetMapping("callback/return")
    public String callBack() {
        // 同步回调给用户展示信息
        return "redirect:" + AlipayConfig.return_order_url;
    }

    // http://hfy4uk.natappfree.cc/api/payment/alipay/callback/notify
    @PostMapping("callback/notify")
    @ResponseBody
    public String callbackNotify(@RequestParam Map<String, String> paramsMap){
        //Map<String, String> paramsMap //将异步通知中收到的所有参数都存放到map中
        System.out.println("异步我来了。。。");
        boolean signVerified = false; //调用SDK验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        /**
         * 商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号；
         * 判断 total_amount 是否确实为该订单的实际金额（即商户订单创建时的金额）；
         * 验证 app_id 是否为该商户本身。
         * 只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时，支付宝才会认定为买家付款成功。
         */
        String outTradeNo = paramsMap.get("out_trade_no");//商户系统中创建的订单号
        //查询数据库
        PaymentInfo paymentInfo=paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());

        String totalAmount = paramsMap.get("total_amount");//订单的实际金额
        String appId = paramsMap.get("app_id");//appId
        String tradeStatus = paramsMap.get("trade_status");//交易状态
        String notifyId = paramsMap.get("notify_id");//通知校验 ID 保存幂等性
        System.out.println("app_id"+app_id);
        if(signVerified){
            // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            if (paymentInfo==null || new BigDecimal("0.01").compareTo(new BigDecimal(totalAmount))!=0 || !appId.equals(app_id)){
                return "failure";
            }
            //放入redis  使用setnx 不存在就放入
            Boolean flag = redisTemplate.opsForValue().setIfAbsent(notifyId, notifyId, 1462, TimeUnit.MINUTES);//写入缓存

            //Map<String,List<Map<String, List<String>>>> map=new HashMap<>();

            if (!flag){
                return "failure";
            }
            if ("TRADE_SUCCESS".equals(tradeStatus)||"TRADE_FINISHED".equals(tradeStatus)){
                //修改pay状态 修改order状态
                paymentService.paySuccess(outTradeNo,PaymentType.ALIPAY.name(),paramsMap);
                return "success";
            }
            return "failure";
        }else{
            // TODO 验签失败则记录异常日志，并在response中返回failure.
            return "failure";
        }
    }

    // 发起退款！http://localhost:8205/api/payment/alipay/refund/20
    @GetMapping("refund/{orderId}")
    @ResponseBody
    public Result refund(@PathVariable(value = "orderId")Long orderId){
        // 调用退款接口
        Boolean flag = alipayService.refund(orderId);
        return Result.ok(flag);
    }

    //http://localhost:8205/api/payment/alipay/closePay/25
    // 根据订单Id关闭订单
    @GetMapping("closePay/{orderId}")
    @ResponseBody
    public Boolean closePay(@PathVariable Long orderId){
        Boolean aBoolean = alipayService.closePay(orderId);
        return aBoolean;
    }

    //http://localhost:8205/api/payment/alipay/checkPayment/30
    // 根据订单Id查询订单
    @GetMapping("checkPayment/{orderId}")
    @ResponseBody
    public Boolean checkPayment(@PathVariable Long orderId){
        Boolean flag  = alipayService.checkPayment(orderId);
        return flag ;
    }

    //outTradeNo, PaymentType.ALIPAY
    @GetMapping("getPaymentInfo/{outTradeNo}")
    @ResponseBody
    public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo) {
        PaymentInfo paymentInfo = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
        if (paymentInfo!=null){
            return paymentInfo;
        }
        return null;
    }
}
